/*
 * This file is part of GuitarMaster.
 * 
 * GuitarMaster is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GuitarMaster is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with Foobar.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.paris5.master2.guitarmaster.service;

import com.paris5.master2.guitarmaster.bean.*;
import com.paris5.master2.guitarmaster.dao.EcomDao;
import com.paris5.master2.guitarmaster.dao.EcomQuery;
import com.paris5.master2.guitarmaster.entity.*;
import com.paris5.master2.guitarmaster.exception.EcomException;
import com.paris5.master2.guitarmaster.exception.EcomQueryException;
import com.paris5.master2.guitarmaster.exception.EcomValidationException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Stateless;

/**
 *
 * @author Leticia Mahamed, Alice Khammy, mourad nedjahi, Saliou Mamadou Barry
 */
@Stateless(mappedName = "admin")
public class ServiceAdmin implements ServiceAdminRemote {

    @EJB
    private EcomDao sdao;
    @EJB
    private ServiceProductRemote serviceProduct;
    @EJB
    private ServiceCustomerRemote serviceCustomer;
    @EJB
    private BidTimerLocal bidTimer;
    @EJB
    private ServiceCartRemoteE serviceCart;
    final int statusAdmin = 2;

    @Override
    public void addProduct(EcomProduct bean) throws EcomValidationException {
        if (bean == null) {
            throw new EcomValidationException("Empty Product sent ! (EcomProduct == null)");
        }
        Product product = new Product(bean);
        sdao.insert(product);
    }

    @Override
    public void addProductType(EcomProductType bean) throws EcomValidationException {
        if (bean == null) {
            throw new EcomValidationException("Empty ProductType sent ! (EcomProductType == null)");
        }
        ProductType productType = new ProductType(bean);
        sdao.insert(productType);
    }

    @Override
    public void updateProductType(EcomProductType bean) throws EcomValidationException {

        if (bean == null) {
            throw new EcomValidationException("Empty Product sent ! (EcomProduct == null)");
        }

        
        ProductType productType=(ProductType) sdao.find(ProductType.class, bean.getIdProductType());
        
        if(productType==null){
            throw new EcomValidationException("ProductType not found ! (EcomProduct == null)");
        }

        ProductType pt = new ProductType(bean);
        pt.setQuantity(productType.getQuantity());
        sdao.update(pt);
    }

    @Override
    public void updateProduct(EcomProduct bean) throws EcomValidationException {
        Product product = (Product) sdao.find(Product.class, bean.getIdProduct());

        if (bean == null) {
            throw new EcomValidationException("Empty Product sent ! (EcomProduct == null)");
        }
        product = UpDateProductFomEcomProduct(product, bean);
        sdao.update(product);
    }

    @Override
    public void addCategory(EcomCategory bean) throws EcomValidationException {
        if (bean == null) {
            throw new EcomValidationException("Empty category sent ! (EcomCategory == null)");
        }
        Category category = new Category(bean);
        sdao.insert(category);
    }

    @Override
    public void updateCategory(EcomCategory bean) throws EcomValidationException {

        if (bean == null) {
            throw new EcomValidationException("Empty country sent ! (EcomProduct == null)");
        }

        Category category = new Category(bean);
        sdao.update(category);
    }

    @Override
    public void removeCategory(EcomCategory bean) throws EcomValidationException {

        if (bean == null) {
            throw new EcomValidationException("Empty country sent ! (EcomProduct == null)");
        }

        Category category = (Category) sdao.find(Category.class, bean.getIdCategory());
        if (category == null) {
            throw new EcomValidationException("This country does not exist in data base");
        }

        sdao.delete(category);
    }

    @Override
    public void withdrawStoreBalance(EcomStore bean, Float amount) throws EcomValidationException {
        if (bean == null) {
            throw new EcomValidationException("Empty Store sent ! (EcomStory == null)");
        }
        Store store = (Store) sdao.find(Store.class, bean.getIdStore());
        if (store == null) {
            throw new EcomValidationException("This Store does not exist in data base");
        }
        Float oldBalance = store.getBalance();
        Float newBalance = oldBalance - amount;
        if (newBalance < 0) {
            throw new EcomValidationException("Requested amount exceeds the balance! impossible operation");
        }
        store.setBalance(newBalance);
        sdao.update(store);
    }

    @Override
    public void setProductToAuction(EcomUser user, EcomProduct bean, float price) throws EcomValidationException, EcomQueryException, EcomException {

        if (bean == null) {
            throw new EcomValidationException("Empty product sent ! (EcomProduct == null)");
        }
        
        User usr = new User(user);
        Product product = new Product(bean);
        sdao.insert(product);
        Date now = new Date();
        product.setBidEndDate(bean.getBidEndDate());
        Bid bid = new Bid();
        bid.setIdUser(usr);
        bid.setIdProduct(product);
        bid.setDateCrea(now);
        bid.setBidPrice(price);
        bid.setIdBid(product.getIdProduct());
        sdao.insert(bid);
        bidTimer.creerBidTimer(bid);
    }

    @Override
    public void addStore(EcomStore bean) throws EcomValidationException {
        if (bean == null) {
            throw new EcomValidationException("Empty Store sent ! (EcomStory == null)");
        }

        Store store = new Store(bean);
        sdao.insert(store);
    }

    @Override
    public void addCountry(EcomCountry bean) throws EcomValidationException {
        if (bean == null) {
            throw new EcomValidationException("Empty Country sent ! (EcomCountry == null)");
        }

        Country country = new Country(bean);
        sdao.insert(country);
    }

    @Override
    public void updateCountry(EcomCountry bean) throws EcomValidationException {

        if (bean == null) {
            throw new EcomValidationException("Empty country sent ! (EcomProduct == null)");
        }

        Country country = new Country(bean);
        sdao.update(country);
    }

    @Override
    public void removeCountry(EcomCountry bean) throws EcomValidationException {

        if (bean == null) {
            throw new EcomValidationException("Empty country sent ! (EcomProduct == null)");
        }

        Country country = (Country) sdao.find(Country.class, bean.getCode());
        if (country == null) {
            throw new EcomValidationException("This country does not exist in data base");
        }

        sdao.delete(country);
    }

    @Override
    public Float getStoreBalance(EcomStore bean) throws EcomValidationException {

        Store store = (Store) sdao.find(Store.class, bean.getIdStore());
        if (store == null) {
            throw new EcomValidationException("This Store does not exist in data base");
        }
        return store.getBalance();
    }

    @Override
    public EcomCountry findCountry(String id) {
        Country country = (Country) sdao.find(Country.class, id);
        if (country != null) {
            return country.getEcomCountry();
        }
        return null;
    }

    @Override
    public void updateStore(EcomStore bean) throws EcomValidationException {

        if (bean == null) {
            throw new EcomValidationException("Empty country sent ! (EcomStore == null)");
        }

        Store store = new Store(bean);
        sdao.update(store);
    }

    @Override
    public void removeProductType(EcomProductType bean) throws EcomValidationException {

        if (bean == null) {
            throw new EcomValidationException("Empty EcomProductType sent ! (EcomStore == null)");
        }

        ProductType productType = (ProductType) sdao.find(ProductType.class, bean.getIdProductType());
        if (productType == null) {
            throw new EcomValidationException("This ProductType does not exist in data base");
        }

        sdao.delete(productType);
    }

    @Override
    public void removeProduct(EcomProduct bean) throws EcomValidationException {

        if (bean == null) {
            throw new EcomValidationException("Empty EcomProduct sent ! (EcomStore == null)");
        }

        Product product = (Product) sdao.find(Product.class, bean.getIdProduct());
        if (product == null) {
            throw new EcomValidationException("This Product does not exist in data base");
        }

        sdao.delete(product);
    }

    @Override
    public void removeStore(EcomStore bean) throws EcomValidationException {

        if (bean == null) {
            throw new EcomValidationException("Empty country sent ! (EcomStore == null)");
        }

        Store store = (Store) sdao.find(Store.class, bean.getIdStore());
        if (store == null) {
            throw new EcomValidationException("This country does not exist in data base");
        }

        sdao.delete(store);
    }

    @Override
    public EcomCategory findCategory(Integer id) {
        Category categ = (Category) sdao.find(Category.class, id);
        if (categ != null) {
            return categ.getEcomCategory();
        }
        return null;
    }

    @Override
    public EcomCategory findCategory(String title) throws EcomQueryException{
        EcomQuery.CATEGORY_BY_TITLE.setSelectQuery();
        ArrayList params = new ArrayList();
        params.add(title);
        Category categ = (Category) sdao.execute(EcomQuery.CATEGORY_BY_TITLE, params);
        if(categ!=null){
            return categ.getEcomCategory();
        }
        return null;
    }
    
    
    @Override
    public EcomStore findStore(int id){
        Store st = (Store) sdao.find(Store.class, id);
        if (st != null) {
            return st.getEcomStore();
        }
        return null;
    }

    @Override
    public EcomStore findStore(String name) throws EcomQueryException {
        EcomQuery.STORE_FIND.setSelectQuery();
        ArrayList params = new ArrayList();
        params.add(name);
        Store st = (Store) sdao.execute(EcomQuery.STORE_FIND, params);
        if (st != null) {
            return st.getEcomStore();
        }
        return null;
    }

    @Override
    public EcomProductType findProductType(String title) throws EcomQueryException {
        EcomQuery.PRODUCT_TYPE_TITLE.setSelectQuery();
        ArrayList params = new ArrayList();
        params.add(title);
        ProductType st = (ProductType) sdao.execute(EcomQuery.PRODUCT_TYPE_TITLE, params);
        if (st != null) {
            return st.getEcomProductType();
        }
        return null;
    }

    /**
     * Cette méthode permet de déposer de l'argent dans un magasin
     *
     * @param bean : Le magasin à mettre à jour
     * @param amount Le montant à ajouter
     * @throws EcomValidationException
     */
    @Override
    public void depositAmount(EcomStore bean, Float amount) throws EcomValidationException {
        if (bean == null) {
            throw new EcomValidationException("Empty Store sent ! (EcomStory == null)");
        }
        Store store = (Store) sdao.find(Store.class, bean.getIdStore());
        if (store == null) {
            throw new EcomValidationException("This Store does not exist in data base");
        }
        Float oldBalance = store.getBalance();
        Float newBalance = oldBalance + amount;
        if (newBalance < 0) {
            throw new EcomValidationException("Requested amount exceeds the balance! impossible operation");
        }
        store.setBalance(newBalance);
        sdao.update(store);
    }

    /**
     * Cette méthode permet de finir une enchère.
     *
     * @param bean
     * @throws EcomValidationException
     * @throws EcomQueryException
     * @throws EcomException
     */
    @Override
    public void endProductToAuction(EcomProduct bean) throws EcomValidationException, EcomQueryException, EcomException {
        if (bean == null) {
            throw new EcomValidationException("Empty product sent ! (EcomProduct == null)");
        }
        Product product = (Product) sdao.find(Product.class, bean.getIdProduct());
        List<EcomBid> bids=serviceProduct.getProductBids(product.getIdProduct(), 0, 2);
        User lastUser=(User) sdao.find(User.class,bids.get(0).getUser().getId());
        Float price=bids.get(0).getBidPrice();
        if(bids!=null && lastUser.getStatus()!=statusAdmin && price<=lastUser.getBalance()){      
            serviceCustomer.withdrawUserBalance(lastUser.getIdUser(),price);
            this.depositAmount(product.getIdStore().getEcomStore(), price);
            product.setStatus(1);         
        }
        else if(bids.size()>0){
            Score score=lastUser.getScore();
            int oldScoreValue=score.getScore();
            int newScoreValue=oldScoreValue>0?oldScoreValue-1:0;
            score.setScore(newScoreValue);
            sdao.update(score);
            product.setBidEndDate(null); 
        }
        sdao.update(product);
    }

    /**
     *
     * @param product
     * @param eProduct
     * @return
     */
    private Product UpDateProductFomEcomProduct(Product product, EcomProduct eProduct) {
        product.setBidEndDate(eProduct.getBidEndDate());
        product.setStatus(eProduct.getStatus());
        ProductType productType = (ProductType) sdao.find(ProductType.class, eProduct.getIdProductType());
        product.setIdProductType(productType);
        product.setUpdateDate(eProduct.getUpdateDate());
        return product;
    }
}
